/*
 * gtk_entry.c
 *
 * Copyright (C) 2012 CADCAM-Servies Franz Reiter (franz.reiter@cadcam.co.at)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *


-----------------------------------------------------
Inputfield.


-----------------------------------------------------
Modifications:
2012-02-01 extracted from ut_gtk.c.  RF.


-----------------------------------------------------
*/
#ifdef globTag
void GUI_ENTRY(){}
#endif
/*!
\file ../gui_gtk/ut_entry.c
\ingroup grp_gui
\code

=====================================================
List_functions_start:

GUI_entry__            inputfield for text
GUI_entry_get          get text from entryField - gives back a Pointer
GUI_entry_pos_get      get cursorPosition
GUI_entry_pos_set      set cursorPosition

GUI_entry_cb           INTERNAL

List_functions_end:
=====================================================

\endcode *//*----------------------------------------



======================================================================
*/





// #include "../xa/MS_Def0.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <gtk/gtk.h>


#include "../ut/ut_umem.h"                     // Memspc

#include "../gui/gui_types.h"                  // TYP_Event..
#include "../gui/gui_base.h"

#include "../gui_gtk/gtk_base.h"
#include "../gui_gtk/gtk_entry.h"
#include "../gui_gtk/gui_gtk_ut.h"

// gtk_core.c:
extern GtkWidget *UI_act_wi;
extern int       UI_fontsizX, UI_fontsizY;




//================================================================
   int GUI_entry_pos_get (MemObj *o_par) {
//================================================================
/// \code
/// GUI_entry_pos_get   get cursorPosition
/// retCod = position; 0=leftmost.
/// \endcode

  int         pTyp;
  Obj_Unknown *go;

  GUI_obj_typ (&pTyp, (void**)&go, o_par);
  if(!pTyp) return (-1);


  return gtk_editable_get_position ((GtkEditable*)go->widget);

}


//================================================================
   int GUI_entry_pos_set (int cPos, MemObj *o_par) {
//================================================================
/// GUI_entry_pos_set   set cursorPosition
/// cPos -1 = last pos.

  int         pTyp;
  Obj_Unknown *go;

  GUI_obj_typ (&pTyp, (void**)&go, o_par);
  if(!pTyp) return (-1);


  gtk_editable_set_position ((GtkEditable*)go->widget, cPos);

  return 0;

}


//================================================================
  char* GUI_entry_get (MemObj *mo) {
//================================================================
/// \code
/// GUI_entry_get get text from entryField - get pointer
/// \endcode

  void   *go, *wo;
  
  go = GUI_obj_pos (mo);
  if(!go) return NULL;
  wo = ((Obj_Entry*)go)->entry;

  return (char*)gtk_entry_get_text(GTK_ENTRY(wo));

}


//=====================================================================
  MemObj GUI_entry__ (MemObj *o_par, char* ltxt, char* etxt,
                      void *funcnam, void *data, int hsiz, int vsiz) {
//=====================================================================
///  
/// \code
///   ltxt:      Labeltext; NULL or "" for none
///   etxt:      Text in Entryfield; NULL oder "" for none
///   funcnam:   callback-function for Keypress & FocusIn-Events (none: NULL)
///   xsiz       0   minimum size (size of caption)
///              1   maximum size (expand inside container)
///              >1  prepare size for <siz> nr of characters
///              <0  absolute size (in pixels)
///
/// prototyp funcnam:
/// int funcnam (MemObj *mo, void **data); 
///   // data=table of 4 pointers;
///   GUI_DATA_EVENT =*(int*)data[0]=TYP_EventEnter|TYP_EventRelease
///   GUI_DATA_S1    =(char*)data[1]=userdata
///   GUI_DATA_I2    =*(int*)data[2]=keyvalue; eg 'a'
///   GUI_DATA_I3    =*(int*)data[3]=state of modifierkeys;
///                                  &1=shift; &4=ctrl; &8=alt.
///                                  &256=MB1; &512=MB2; &1024=MB3.
///   GUI_OBJ_TYP(mo)  = TYP_GUI_Entry
/// 
/// Example without callback-function:
///   we1 = GUI_entry__ (&box1, "0.0", "sum", NULL, NULL, 0, 0);
///
///   printf(" |%s|\n",GUI_entry_get(&we1));
///
/// Example with callback-function:
///   we2 = GUI_entry__ (&box1, "0.0", "sum", went_cb, NULL, 10, 1);
///   ..
///   int we2_cb (MemObj *mo, void **data) {
///     printf(" event=%d typ=%d\n",GUI_DATA_EVENT,GUI_OBJ_TYP(mo));
///     if(GUI_DATA_EVENT != TYP_EventRelease) return 0;  // skip enter-event
///     printf(" |%s|\n",GUI_entry_get(mo));
///   }
///
/// \endcode




  int        is, i1;
  void       *w_par, *wb;
  GtkWidget  *w1, *w2, *box1;
  Obj_Entry  *gEnt;


  printf("GUI_entry__ |%s|%s| %d %d\n",ltxt,etxt,hsiz,vsiz);

  // get gtk-widget for parentBox from MemObj
  w_par = GUI_obj_parentBox (o_par);
  if(!w_par) return (UME_obj_invalid_set (-2));


  // get address & memspc
  GUI_obj_spc ((void**)&gEnt, sizeof(Obj_Entry));
  if(!gEnt) return (UME_obj_invalid_set (-3));



  w1 = gtk_entry_new ();

  if (funcnam) {
    gtk_widget_set_events (GTK_WIDGET(w1),
                           GDK_FOCUS_CHANGE_MASK|
                           GDK_BUTTON_RELEASE_MASK);

    g_signal_connect (G_OBJECT (w1),
                        "key-release-event",  //"key-press-event",
                        G_CALLBACK (GUI_entry_cb),
                        PTR_MEMOBJ(gEnt->mem_obj));    //(void*)gEnt);

    // focus-in-event erforderlich f CAD-select-objects
    g_signal_connect (G_OBJECT (w1),
                        "focus-in-event",
                        G_CALLBACK (GUI_entry_cb),
                        PTR_MEMOBJ(gEnt->mem_obj));    //(void*)gEnt);
  }


  // preset Text
  i1 = 0;
  if(etxt) i1 = strlen(etxt);
  if(i1 > 0) {
    /* printf("preset Text /%s/\n",etxt); */
    gtk_entry_set_text (GTK_ENTRY(w1), etxt);
  }


  //----------------------------------------------------------------
  if((vsiz == 0) && (hsiz != 0)) vsiz = 1;

  // label + entry
  if (ltxt) {
    // printf("Labelext /%s/\n",ltxt);
#ifdef GTK2
    box1 = gtk_hbox_new (FALSE, 0);
#else
    box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
#endif

    // pack label into box1
    w2 = gtk_label_new (ltxt);
    gtk_container_add (GTK_CONTAINER (box1), w2);
    gtk_container_add (GTK_CONTAINER (box1), w1);

    GUI_packwn (w_par, box1, hsiz, vsiz);
    gtk_widget_show (w1);
    gtk_widget_show (w2);

  } else {
    GUI_packwn (w_par, w1, hsiz, vsiz);
  }


  // fill obj
  gEnt->gio_typ  = TYP_GUI_Entry;
  gEnt->entry    = w1;
  gEnt->data     = data;
  gEnt->uFunc    = funcnam;

  // return memObj
  return (((Obj_Unknown*)gEnt)->mem_obj);

}


//================================================================
  int GUI_entry_cb (void *parent, void *event, MemObj mo) {
//================================================================
/// \code
/// INTERNAL
/// returns 0=event   TYP_EventEnter|TYP_EventRelease
///         1=device  TYP_DeviceKeyb
///         2=userdata
///         3=key
///         4=modfier
/// \endcode

  int          ikey, imod, iEv;
  void         *pTab[4];
  Obj_Entry    *go;


  printf("GUI_entry_cb %d %d\n",mo.mbID,mo.ioff);
  printf(" ev=%d\n",((GdkEvent*)event)->type);

  go = GUI_obj_pos (&mo);
  if(!go) return 0;
  if(!go->uFunc) return 0;


  if(((GdkEvent*)event)->type == GDK_FOCUS_CHANGE) {
    // GdkEventFocus 
    ikey = 0;
    // imod = ((GdkEventFocus*)event)->in;                always 1

    // test "has-focus" property
    // g_object_get (parent, "has-focus", &imod, NULL);   always 1
    imod = 0;

    iEv = TYP_EventEnter;
  }


  if(((GdkEvent*)event)->type == GDK_KEY_RELEASE) {
    // GdkEventKey   keyval, state
    ikey = ((GdkEventKey*)event)->keyval;
    imod = ((GdkEventKey*)event)->state;

    iEv = TYP_EventRelease;
  }

  pTab[0] = &iEv;
  pTab[1] = go->data;
  pTab[2] = &ikey;
  pTab[3] = &imod;

  go->uFunc (go, pTab);

}


// EOF
